﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrayParrot.Web.Controls//.Datatables.Filters
{
    /// <summary>
    /// Class fo output filter params...
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SelectFilterResult<T> where T : class
    {
        public int Total { get; set; }
        public T Results { get; set; }

        public SelectFilterResult()
        {
        }

        //public IEnumerable<T> GetData<D>(SelectFilterParams data, IEnumerable<D> value)
        //{
        //    IEnumerable<T> retValue = null;

        //    T objs2 = null;
        //    if ((data == null) || (string.IsNullOrWhiteSpace(data.SearchTerm)))
        //    {
        //        objs2 = value.Select(x => new T() { name = x, value = x });
        //    }
        //    else
        //    {
        //        objs2 = value.Select(x => new T() { name = x, value = x }).Where(x=>x.name.ToLower().Contains(data.SearchTerm.ToLower()));
        //    }

        //    if ((data != null) && (data.PageNumber != 0) && (data.PageSize != 0))
        //    {
        //        retValue.Results = objs2.Skip((data.PageNumber - 1) * data.PageSize).Take(data.PageSize).ToList();
        //    }
        //    else
        //    {
        //        retValue.Results = objs2.ToList();
        //    }
        //}
    }

    /// <summary>
    /// Class for filter input params...
    /// </summary>
    public class SelectFilterParams
    {
        public string SearchTerm { get; set; }
        public int PageSize { get; set; }
        public int PageNumber { get; set; }
    }

    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    //[TypeConverter(typeof(ExpandableObjectConverter))]
    public class SelectColumnFilter : ColumnFilter
    {
        /// <summary>
        /// The m_options
        /// </summary>
        private string m_options = string.Empty;

        public string IdProp { get; set; }
        public string TextProp { get; set; }

        public bool EnablePagination { get; set; }
        public int PageSize { get; set; }

        /// <summary>
        /// Gets or sets the type of the select.
        /// </summary>
        /// <value>
        /// The type of the select.
        /// </value>
        public SelectTypes SelectType { get; set; }
        /// <summary>
        /// Gets or sets the minimum length of the input.
        /// </summary>
        /// <value>
        /// The minimum length of the input.
        /// </value>
        public int MinimumInputLength { get; set; }
        /// <summary>
        /// Gets or sets the delay.
        /// </summary>
        /// <value>
        /// The delay.
        /// </value>
        public uint Delay { get; set; }
        /// <summary>
        /// Gets or sets the URL.
        /// </summary>
        /// <value>
        /// The URL.
        /// </value>
        public string Url { get; set; }

        /// <summary>
        /// Gets or sets the width.
        /// </summary>
        /// <value>
        /// The width.
        /// </value>
        public int Width { get; set; }

        public SelectColumnFilter()
        {
            this.Width = 100;
            this.Type = FilterTypes.Select;
            this.MinimumInputLength = 0;
            this.Delay = 250;
            this.Url = string.Empty;
            this.SelectType = SelectTypes.Simple;
            this.IdProp = "id";
            this.TextProp = "text";
            this.EnablePagination = true;
            this.PageSize = 20;
        }

        protected internal string ComposeOptions()
        {
            string retValue = string.Empty;

            if (this.MinimumInputLength > 1)
            {
                this.SelectType = SelectTypes.Select2;
            }

            StringBuilder sb = new StringBuilder();

            sb.Append(", select_type_options: {\n");
            sb.Append("   dropdownAutoWidth : true,\n");
            sb.AppendFormat("   width : '{0}px',\n", this.Width);

            if (this.SelectType == SelectTypes.Simple)
            {
                // yadcf standard options...
                sb.Append("   minimumResultsForSearch : Infinity,\n");
                if (!string.IsNullOrWhiteSpace(this.Url))
                {
                    sb.AppendFormat("   ajax: {{ url: '{0}',\n", this.Url);
                    sb.Append("   dataType: 'json',\n");
                    sb.Append("   type: 'POST',\n");
                    //sb.Append("   params: { contentType: 'application/json; charset=utf-8' },\n");

                    sb.Append("   data: function (params) {\n");
                    sb.Append("      return {\n");
                    sb.Append("          searchTerm: params.term\n");
                    sb.Append("      };\n");
                    sb.Append("   },\n");

                    sb.Append("   processResults: function (data, params) {\n");
                    sb.Append("       return {\n");
                    sb.Append("           results: $.map(data.Results, function (item) {\n");
                    sb.Append("               var obj = {\n");
                    sb.AppendFormat("                text: item.{0},\n", this.TextProp);
                    sb.AppendFormat("                id: item.{0}\n", this.IdProp);
                    sb.Append("               };\n");
                    sb.Append("               return obj;\n");
                    sb.Append("           })\n");
                    sb.Append("       };\n");
                    sb.Append("   }\n");
                    sb.Append("}\n");
                }
                sb.Append("}\n");
            }
            else
            {
                // select2 options...
                sb.AppendFormat("   minimumResultsForSearch : {0},\n", this.MinimumInputLength);

                if (!string.IsNullOrWhiteSpace(this.Url))
                {
                    sb.AppendFormat("   ajax: {{ url: '{0}',\n", this.Url);
                    sb.Append("   dataType: 'json',\n");
                    sb.Append("   type: 'POST',\n");
                    //sb.Append("   params: { contentType: 'application/json; charset=utf-8' },\n");

                    sb.Append("   data: function (params) {\n");

                    if (this.EnablePagination)
                    {
                        sb.Append("      params.page = params.page || 1;\n");
                    }
                    sb.Append("      return {\n");
                    sb.Append("          searchTerm: params.term\n");

                    if (this.EnablePagination)
                    {
                        sb.AppendFormat("          ,pageSize: {0}\n", this.PageSize);
                        sb.Append("          ,pageNumber: params.page\n");
                    }

                    sb.Append("      };\n");
                    sb.Append("   },\n");

                    sb.Append("processResults: function (data, params) {\n");

                    if (this.EnablePagination)
                    {
                        sb.Append("    params.page = params.page || 1;\n");
                    }

                    sb.Append("    return {\n");
                    sb.Append("        results: $.map(data.Results, function (item) {\n");

                    sb.Append("            var obj = {\n");
                    sb.AppendFormat("                text: item.{0},\n", this.TextProp);
                    sb.AppendFormat("                id: item.{0}\n", this.IdProp);
                    sb.Append("            };\n");

                    sb.Append("            return obj;\n");
                    sb.Append("        })\n");

                    if (this.EnablePagination)
                    {
                        sb.Append("        ,pagination: {\n");
                        sb.AppendFormat("            more: (params.page * {0}) < data.Total\n", this.PageSize);
                        sb.Append("        }\n");
                    }

                    sb.Append("    };\n");
                    sb.Append("}\n");

                    sb.Append("}\n");
                }
                sb.Append("}\n");
            }


            retValue = sb.ToString();

            return retValue;
        }

        /// <summary>
        /// Compensa un problema che si presenta sulla colonna select del filtro quando in modalità SIMPLE...
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="result">The result.</param>
        /// <param name="fieldName">Name of the field.</param>
        /// <returns></returns>
        public static JObject Sanitize<T>(DTResult<T> result, string fieldName)
        {
            JObject jo = JObject.FromObject(result);
            jo.Add(fieldName, JToken.FromObject(""));

            return jo;
        }
    }
}
